﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Powersource.WebApp.Services;
using System.IO.Compression;

namespace Powersource_UnitTests.WebServiceTest
{
    [TestClass]
    public class RemoteBuildBridgeTest
    {
        private RemoteBuildBridge BuildBridge;
        private string drive = System.Environment.GetEnvironmentVariable("SystemDrive");
        private string basePath = "psdrops";
        private string downloadPath = "download";
        private string copyAndUnzipPath = "copy";
        private string guid = "37331AEE-E9D4-40F0-A868-6FC0DD1DD7F9";
        private string buildName = "testbuild";
        private string buildVersion = "testVersion1";
        private string[] testfiles = { "test.txt", "test.dll", "test.exe" };
        private string copyfile = "ziptest";
        private string fullBasePath = null;
        private string fullDownloadPath = null;
        private string fullCopyAndUnzipPath = null;
        private string dir = null;

        // Use TestInitialize to run code before running each test 
        [TestInitialize()]
        public void MyTestInitialize()
        {
            BuildBridge = new RemoteBuildBridge();

            fullBasePath = drive + "\\" + basePath;
            fullDownloadPath = drive + "\\" + downloadPath;
            fullCopyAndUnzipPath = drive + "\\" + copyAndUnzipPath;
            dir = fullBasePath + "\\" + guid + "\\" + buildName + "\\" + buildVersion;
            if (!Directory.Exists(fullDownloadPath)) Directory.CreateDirectory(fullDownloadPath);
            if (!Directory.Exists(fullCopyAndUnzipPath)) Directory.CreateDirectory(fullCopyAndUnzipPath);
            if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
            foreach (var file in testfiles)
            {
                File.Create(dir + "\\" + file).Close();
            }

        }

        // Use TestCleanup to run code after each test has run
        [TestCleanup()]
        public void MyTestCleanup()
        {
            BuildBridge = null;

            Directory.Delete(fullBasePath + "\\" + guid, true);
            Directory.Delete(fullDownloadPath, true);
            Directory.Delete(fullCopyAndUnzipPath, true);
            fullBasePath = null;
            fullDownloadPath = null;
            fullCopyAndUnzipPath = null;
            dir = null;
        }

        [TestMethod]
        public void RemoteBuildBridgeTestGetConfiguration()
        {
            var config = BuildBridge.GetConfiguration();
            Assert.IsNotNull(config, "Remote Build Bridge returns null configuration object.");
            Assert.IsNotNull(config.UNCPathBase, "Remote Build Bridge returns null configuration object.");
        }

        [TestMethod]
        public void RemoteBuildBridgeTestGetRemoteBuild()
        {
            BuildBridge.ZipFileLocation = new DirectoryInfo(fullDownloadPath);
            using (var s = BuildBridge.GetRemoteBuild(new Guid(guid), buildName, buildVersion))
            {
                using (var s2 = File.Open(fullCopyAndUnzipPath + "\\" + copyfile, FileMode.Create, FileAccess.Write))
                {
                    s.CopyTo(s2);
                }
            }

            var res = new List<string>(Directory.GetFiles(fullDownloadPath));
            Assert.AreEqual(1, res.Count, "More/less than one file created by service");

            ZipFile.ExtractToDirectory(fullCopyAndUnzipPath + "\\" + copyfile, fullCopyAndUnzipPath);
            res = new List<string>(Directory.GetFiles(fullCopyAndUnzipPath, "test*"));
            Assert.AreEqual(3, res.Count, "Wrong files zipped by service");

            BuildBridge.Dispose();
            foreach (var item in BuildBridge.StreamsToDispose)
            {
                Assert.IsFalse(item.CanRead || item.CanSeek || item.CanTimeout || item.CanWrite, "Streams not closed properly)");
            }
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void RemoteBuildBridgeTestEmptyGuid()
        {
            using (var s = BuildBridge.GetRemoteBuild(Guid.Empty, buildName, buildVersion)) { }
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void RemoteBuildBridgeTestEmptyName()
        {
            using (var s = BuildBridge.GetRemoteBuild(new Guid(guid), "", buildVersion)) { }
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void RemoteBuildBridgeTestEmptyNumber()
        {
            using (var s = BuildBridge.GetRemoteBuild(new Guid(guid), buildName, "")) { }
        }

        [TestMethod]
        [ExpectedException(typeof(InvalidOperationException))]
        public void RemoteBuildBridgeTestBadZipFileLocation()
        {
            BuildBridge.ZipFileLocation = new DirectoryInfo("wrong directory");
            using (var s = BuildBridge.GetRemoteBuild(new Guid(guid), buildName, buildVersion)) { }
        }
    }
}
